/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import database.Certificate;
import database.User;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.SecretKey;
import security.*;
import others.*;


public class OwnServer extends MyServer implements Runnable{
   
    ServerSocket serversocket = null;
    Socket socket = null;
    SecretKey clientKey;
    PrintWriter printwriter;
     BufferedReader bufferedreader;
     String username=null;
    
    public OwnServer(int p){
    startPort=p;
    }
    
    void sendText(String s){
   try{
      byte[] tekst = SymmetricCipher.encrypt(s.getBytes(), clientKey);
      String tosend = Serializator.serializ(tekst);
      //System.out.println("Wysyłam:"+tekst+ " =>" + new String(SymmetricCipher.decrypt(tekst, myKey))+"\n"+tosend);
      printwriter.println(tosend);
   }catch(Exception e){System.out.println("Send error:"+e);}
  }
    
    String getText() {
        try {
            String lineread;
            lineread = bufferedreader.readLine();
            if (lineread==null) return null;
            lineread=new String(    SymmetricCipher.decrypt((byte[])Serializator.deserialize(lineread),clientKey   ),"UTF8"  );
            return lineread;
        } catch (Exception ex) {Logger.getLogger(OwnServer.class.getName()).log(Level.SEVERE, null, ex); }
        return null;
    }

    @Override
    public void run() {
      
    try{
      serversocket = new ServerSocket(startPort);
      System.out.println(":>Serwer potomny wystartował na porcie "+startPort);
 
      socket = serversocket.accept();
 
      InputStreamReader inputstreamreader = new InputStreamReader(socket.getInputStream());
      bufferedreader = new BufferedReader(inputstreamreader);
      printwriter = new PrintWriter(socket.getOutputStream(),true);
      String datetimestring = (Calendar.getInstance()).getTime().toString();
      // printwriter.println("You connected to the Simple Server at " + datetimestring);
       
 
      String lineread = "";
      lineread += bufferedreader.readLine();
     lineread =new String( AsymmetricCipher.decrypt((byte[])Serializator.deserialize(lineread), MyServer.keypair.getPrivate()),"UTF8"); try {} catch(Exception e){} //dekodowanie
      clientKey = (SecretKey) Serializator.deserialize(lineread);
      System.out.println(":>Odebrałem klucz i zdekodowałem następujący klucz symetryczny: "+lineread);
      
      
      while (1>0 ){
          lineread=getText();
          System.out.println(":>Odebrano: "+lineread);
          
        if (lineread.equals("zaloguj")) logowanie();
        else 
        if (lineread.equals("kimjestem")) {if (username==null) sendText("niezalogowany"); else sendText("Zalogowany jako: "+username);}
        else 
         if (lineread.equals("dajcertyfikat")) {makeCert();}
        else
        if (lineread.equals("sprawdzcertyfikat")) {testCert();}
        else
        if (lineread.equals("koniec")){ sendText("Dowidzenia");break;}
        else sendText("Nierozpoznana komenda");
      }
      
      
      
      
      int port = startPort-8181;
       synchronized(MyServer.gniazdaTab){
       MyServer.gniazdaTab[port]=false;
       System.out.println("Zamykam połączenie.");
       }
      
      bufferedreader.close();
      inputstreamreader.close();
      printwriter.close();
      socket.close();
        
      
    }catch(UnknownHostException unhe){
      System.out.println("UnknownHostException: " + unhe.getMessage());
    }catch(InterruptedIOException intioe){
      System.out.println("Timeout while attempting to establish socket connection.");
    }catch(Exception ioe){
      System.out.println("IOExce " + ioe.getMessage());
    }finally{
       int port = startPort-8181;
       synchronized(MyServer.gniazdaTab){
       MyServer.gniazdaTab[port]=false;
       }
       
      try{
        socket.close();
        serversocket.close();
      }catch(IOException ioe){
        System.out.println("IOEx: " + ioe.getMessage());
      }
    }
    }
    
    void makeCert(){
         String msg=null;
         if (username==null) {sendText("niezalogowany"); return;}
         
        try{
            Certificate c = new Certificate();
            c.login = username;
            c.data = (Calendar.getInstance()).getTime().toString();
            String ser = Serializator.serializ(c);
            byte[] out = SymmetricCipher.encrypt(ser.getBytes(), securekey);
            msg = Serializator.serializ(out);
            sendText(msg);
        }catch(Exception e){}
        
        
    }

    private void testCert() {
        String msg = getText();
        System.out.println("Wczytano string do certyowania");
        try{
            byte[] in = (byte[]) Serializator.deserialize(msg);
            String temp = new String(SymmetricCipher.decrypt(in, securekey));
            Certificate c = (Certificate) Serializator.deserialize(temp);
            sendText("Certyfikat poprawny, wystawiiony na: "+c.login+" z datą "+c.data);
        }catch(Exception e){sendText("Certyfikat niepoprawny");}
    }
    
    
    private void logowanie() {
        String a, b;
        sendText("Logowanie (hasło należy podać w nowej linii)");
        System.out.println(":>Logowanie");
        a = getText();
        sendText("Otrzymano login");
        b= getText();
        User temp = new User();
        temp.name=a;
        
        boolean logok=false;
        try {
        int id=L.indexOf(temp);
        User u = L.get(id);
        logok = u.pass.equals(MD5.getMD5(b));
        } catch(Exception e){ sendText("błąd logowania");}
        if (logok){
        username=a;
        sendText("Zalogowano poprawnie jako:" + a);
        return;
        }
        sendText("Błąd logowania");
    }

    
}
